package cn.kent.high.juc.atomic;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 使用AtomicLong类实现递增，底层使用的是CAS非阻塞算法
 * 优点：相比synchronized关键字(阻塞算法)，性能更好。
 * 缺点：高并发下还是会有性能问题
 *
 * 解决方案：引入LongAdder类 {@link java.util.concurrent.atomic.LongAdder}
 */
public class AtomicTest {
    private static AtomicLong atomicLong = new AtomicLong();
    // private static Integer num = 0; // 多线程下会出错
    // 构建数据源
    private static Integer[] arrOne = new Integer[]{0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0};
    private static Integer[] arrTwo = new Integer[]{10, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0, 0, 1, 34, 0, 6, 56, 45, 7, 5, 0};

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < arrOne.length; i++) {
                    if (arrOne[i] == 0) {
                        atomicLong.incrementAndGet();
                        // num++;
                    }
                }
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < arrTwo.length; i++) {
                    if (arrTwo[i] == 0) {
                        atomicLong.incrementAndGet();
                        // num++;
                    }
                }
            }
        });
        thread2.start();
        thread.start();

        thread.join();
        thread2.join();

        System.out.println("count 0: " + atomicLong.get());
        // System.out.println("count 0: "+num);
    }
}
